﻿using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml;

namespace Universe.WCF.Behaviors.Test
{
    using System.Diagnostics;
    using System.Net;
    using System.Net.Sockets;

    class MyEnvionment
    {
        public static ServiceHost CreateService<Contract, Service>()
        {
            ServiceHost sh = new ServiceHost(typeof(Service));
            BasicHttpBinding pipe = new BasicHttpBinding(BasicHttpSecurityMode.None);
            pipe.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
            pipe.MaxReceivedMessageSize = Int32.MaxValue;
            string uri = GetContractUri<Contract>();
            EndpointAddress endpoint = new EndpointAddress(uri);
            ServiceEndpoint ep = sh.AddServiceEndpoint(typeof(Contract), pipe, endpoint.Uri);
            return sh;
        }

        public static ChannelFactory<Contract> CreateProxy<Contract>()
        {
            BasicHttpBinding http = new BasicHttpBinding(BasicHttpSecurityMode.None);
            http.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
            http.MaxReceivedMessageSize = Int32.MaxValue;
            http.OpenTimeout = TimeSpan.FromSeconds(15);
            http.SendTimeout = TimeSpan.FromSeconds(15);
            ChannelFactory<Contract> cf = new ChannelFactory<Contract>(http);
            return cf;
        }

        public static string GetContractUri<Contract>()
        {
            return string.Format("http://localhost:{0}/my/{1}", GetTcpPort(), typeof(Contract).Name);
        }

        public static EndpointAddress GetEndPointUri<Contract>()
        {
            return
                new EndpointAddress(
                    string.Format("http://localhost:{0}/my/{1}", GetTcpPort(), typeof(Contract).Name)
                    );
        }


        private static int TcpPort = 0;

        static int GetTcpPort()
        {
            if (TcpPort == 0)
            {
                TcpListener l = new TcpListener(IPAddress.Loopback, 0);
                l.Start();
                int port = ((IPEndPoint)l.LocalEndpoint).Port;
                l.Stop();
                TcpPort = port;
                Trace.WriteLine("  Working port is: " + port);
                return port;
            }

            return TcpPort;
        }

        public static void ResetTcpPort()
        {
            TcpPort = 0;
        }


    }

    
    class MyEnvionment_OnPipes
    {
        public static ServiceHost CreateService<Contract, Service>()
        {
            ServiceHost sh = new ServiceHost(typeof(Service));
            NetNamedPipeBinding pipe = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
            pipe.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
            pipe.MaxReceivedMessageSize = Int32.MaxValue;
            string uri = string.Format("net.pipe://localhost/my/{0}", typeof(Contract).Name);
            EndpointAddress endpoint = new EndpointAddress(uri);
            ServiceEndpoint ep = sh.AddServiceEndpoint(typeof(Contract), pipe, endpoint.Uri);
            return sh;
        }

        public static ChannelFactory<Contract> CreateProxy<Contract>()
        {
            NetNamedPipeBinding pipe = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
            pipe.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
            pipe.MaxReceivedMessageSize = Int32.MaxValue;
            ChannelFactory<Contract> cf = new ChannelFactory<Contract>(pipe);
            return cf;

        }

        public static string GetContractUri<Contract>()
        {
            return string.Format("net.pipe://localhost/my/{0}", typeof(Contract).Name);
        }

        public static EndpointAddress GetEndPointUri<Contract>()
        {
            return
                new EndpointAddress(
                    string.Format("net.pipe://localhost/my/{0}", typeof(Contract).Name)
                    );
        }
    }
}
